function [best_schedule, best_score] = optimizer_systematic_search_bottleneck(initial_schedule, initial_history, initial_score, G, code_map, is_ancestor, options)
    % V5 更新: 将验证函数 is_schedule_dependency_valid 作为一个外部文件调用。
    
    current_schedule = initial_schedule;
    best_score = initial_score;
    current_history = initial_history;
    num_nodes = numnodes(G);
    
    p = gcp('nocreate');
    if isempty(p), num_cores = 1; else, num_cores = p.NumWorkers; end
    
    start_time = tic;
    
    for pass_num = 1:options.max_passes
        if toc(start_time) > (options.time_limit_minutes * 60)
            fprintf('  阶段二 > 已达到 %g 分钟时间上限，提前终止优化。\n', options.time_limit_minutes);
            break;
        end

        fprintf('  阶段二 > 开始第 %d / %d 轮 (当前最优: %d)\n', pass_num, options.max_passes, best_score);
        improvement_found_in_pass = false;
        
        % --- 候选生成 ... (此处代码与上一版完全相同, 已省略以保持简洁) ---
        candidate_pool = [];
        attempts = 0;
        while isempty(candidate_pool) && attempts < 10
            attempts = attempts + 1;
            [~, peak_idx] = max(current_history);
            search_space_indices = 1:peak_idx;
            if isempty(search_space_indices) || peak_idx == 0, search_space_indices = 1:num_nodes; end
            num_focus_nodes = min(options.num_focus_nodes_multiplier * num_cores, length(search_space_indices));
            focus_nodes_indices = search_space_indices(randperm(length(search_space_indices), num_focus_nodes));
            focus_nodes = current_schedule(focus_nodes_indices);
            candidate_pool_cell = cell(length(focus_nodes), 1);
            parfor i = 1:length(focus_nodes)
                focus_node_inner = focus_nodes(i);
                partners = [];
                for j = 1:num_nodes
                    partner_node_inner = current_schedule(j);
                    if focus_node_inner == partner_node_inner, continue; end
                    if ~is_ancestor(focus_node_inner, partner_node_inner) && ~is_ancestor(partner_node_inner, focus_node_inner)
                        partners(end+1, :) = [focus_node_inner, partner_node_inner];
                    end
                end
                candidate_pool_cell{i} = partners;
            end
            candidate_pool = vertcat(candidate_pool_cell{:});
        end
        if isempty(candidate_pool)
            fprintf('    > 警告: 尝试 %d 次后仍未找到可交换的节点对。跳过本轮。\n', attempts);
            continue; 
        end
        shuffled_candidates = candidate_pool(randperm(size(candidate_pool, 1)), :);
        fprintf('    > 已成功生成 %d 对候选交换方案，开始分批评估...\n', size(shuffled_candidates, 1));
        batch_size = options.batch_size_multiplier * num_cores;
        
        % --- 分批并行评估与抢先更新 ---
        for batch_start = 1:batch_size:size(shuffled_candidates, 1)
            batch_end = min(batch_start + batch_size - 1, size(shuffled_candidates, 1));
            current_batch = shuffled_candidates(batch_start:batch_end, :);
            
            batch_scores = ones(size(current_batch, 1), 1) * inf;
            batch_schedules = cell(size(current_batch, 1), 1);
            
            parfor k = 1:size(current_batch, 1)
                node_A = current_batch(k, 1);
                node_B = current_batch(k, 2);
                
                local_schedule = current_schedule;
                pos_A = find(local_schedule == node_A, 1);
                pos_B = find(local_schedule == node_B, 1);
                
                temp_schedule = local_schedule;
                temp_schedule(pos_A) = node_B;
                temp_schedule(pos_B) = node_A;
                
                % --- 【核心逻辑】调用外部的、完整的验证函数 ---
                if is_schedule_dependency_valid(temp_schedule, is_ancestor) && is_l0_schedule_valid(temp_schedule, G, code_map)
                    batch_schedules{k} = temp_schedule;
                    [batch_scores(k), ~] = calculate_max_vstay(temp_schedule, G, code_map);
                end
            end
            
            [best_batch_score, best_batch_idx] = min(batch_scores);
            if best_batch_score < best_score
                fprintf('    > 发现更优交换, 分数从 %d -> %d\n', best_score, best_batch_score);
                best_score = best_batch_score;
                current_schedule = batch_schedules{best_batch_idx};
                [~, current_history] = calculate_max_vstay(current_schedule, G, code_map);
                improvement_found_in_pass = true;
                break; 
            end
        end
        
        if ~improvement_found_in_pass
            fprintf('  阶段二 > 在第 %d 轮未发现任何改进，提前终止优化。\n', pass_num);
            break;
        end
    end
    
    best_schedule = current_schedule;
end